"""
本文件用于使用贪心策略对游戏进行求解
设计：为了避免左右来回摆动，设置走过的路径附带惩罚的参数
迷宫算法设计：
看到一个想法——先按照贪心的方法进行寻路，并做好标记，记好路线
当发现四周都是墙壁或者走过的路线的时候
递归进行原路返回，直到某一个返回点发现有没走过的路线
"""
from config import *
from typing import Tuple, Set, List
class GreedyPlanner:
    def __init__(self, maze_grid):
        """
        :param maze_grid: 迷宫网格(共同维护)
        """
        self.maze = maze_grid
        self.rows = len(maze_grid)
        self.cols = len(maze_grid[0])
        self.value_map = {
            GOLD: 5, TRAP: -3, BOSS: 15, EXIT: 100,  # 给予EXIT很高的价值
            PATH: 0, START: 0,
        }

    # 用于全盘AI规划
    def find_start(self):
        for r, row in enumerate(self.maze):
            for c, cell in enumerate(row):
                if cell == START:
                    return r, c
        return None # 没有起点

    def get_next_move(self, current_pos: Tuple[int, int], visited: Set[Tuple[int, int]], path_history: List[Tuple[int, int]]):
        """
        根据带记忆的贪心策略决定下一步的移动方向。
        视野是3x3的，打算将返回的坐标进行高亮显示
        :return: 目标坐标
        """
        r, c = current_pos

        # 正常探索，初始化为极小值
        # 思考：“踩陷阱也比往回走强”
        best_move = None
        max_value = -float('inf')

        for dr in [-1, 0, 1]:
            for dc in [-1, 0, 1]:
                # 跳过(0,0)这个中心点，即当前位置
                if dr == 0 and dc == 0:
                    continue
                nr, nc = r + dr, c + dc

                if 0 <= nr < self.rows and 0 <= nc < self.cols and self.maze[nr][nc] != WALL:
                    if (nr, nc) not in visited:
                        cell_value = self.value_map.get(self.maze[nr][nc], 0)
                        if cell_value > max_value:
                            max_value = cell_value
                            best_move = (nr, nc)
        # 找到了只是返回，走不走由玩家决定
        if best_move:
            return best_move

        # 回溯
        if len(path_history) > 1:
            return path_history[-2]

        # 暂时没考虑到的异常
        return None

    def calculate_full_path(self):
        """
        一个自洽的、用于全盘AI规划的方法。
        它自己管理临时的状态，不依赖外部。
        """
        start_pos = self.find_start()
        if not start_pos: return [], 0

        # 临时状态变量
        temp_visited = {start_pos}
        temp_path_history = [start_pos]
        full_trace = [start_pos]  # 记录所有脚印，包括来回

        while True:
            current_pos = temp_path_history[-1]
            if self.maze[current_pos[0]][current_pos[1]] == EXIT:
                break

            next_move, move_mode = self.get_next_move(current_pos, temp_visited, temp_path_history)

            if move_mode == "STUCK":
                break

            full_trace.append(next_move)
            if move_mode == "EXPLORE":
                temp_visited.add(next_move)
                temp_path_history.append(next_move)
            elif move_mode == "BACKTRACK":
                temp_path_history.pop()

        # 计算得分 (基于最终不重复访问的格子)
        score = 0
        for pos in temp_visited:
            score += self.value_map.get(self.maze[pos[0]][pos[1]], 0)
        score -= self.value_map.get(START, 0)  # 起点分通常不计

        return full_trace, score